package cn.blnp.net.flowable.boot.localize.dynamic.jump.gateway;

import cn.blnp.net.flowable.boot.utils.ListUtils;
import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.filter.SimplePropertyPreFilter;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.IdentityService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ExecutionQuery;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <h3>流程动态跳转与网关结合案例</h3>
 *
 * @author <a href="mailto:blnp.yibin@qq.com">lyb</a>
 * @version 1.0
 * @since 2025/6/18 14:18
 */
@Slf4j
@SpringBootTest
public class DynamicJumpGatewayTest {

    @Resource
    private RepositoryService repositoryService;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private IdentityService identityService;
    @Resource
    private TaskService taskService;

    SimplePropertyPreFilter taskFilter = new SimplePropertyPreFilter(Task.class, "id",
            "name", "executionId", "taskDefinitionKey", "assignee", "owner");
    SimplePropertyPreFilter executionFilter = new SimplePropertyPreFilter(Execution.class,
            "id", "parentId", "processInstanceId", "activityId", "isScope");

    /**
     *  <h1>网关流程动态跳转演示</h1>
     *  <p>
     *     示例流程是个较为复杂的案例，使用了2个并行网关、3个包容网关和1个排他网关构成了一个较为复杂的流程。
     *      <ul>
     *          <li><b>流程定义文件：</b>{@link flow/gatewayDynamicJumpProcess.bpmn20.xml}</li>
     *          <li>
     *              <b>流程预览图：</b></br>
     *              <img src="https://cdn4.winhlb.com/2025/06/18/68525b8df0798.png" >
     *          </li>
     *      </ul>
     *  </p>
     **/
    @Test
    public void test() {
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("flow/gatewayDynamicJumpProcess.bpmn20.xml")
                .name("动态跳转基础案例")
                .deploy();
        //流程定义信息
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deploy.getId())
                .singleResult();
        log.info("流程定义ID：{}", processDefinition.getId());

        //初始化流程变量
        Map<String, Object> variables = MapUtil.builder(new HashMap<String, Object>())
                .put("condition1", true)
                .put("condition2", true)
                .put("condition3", true)
                .put("condition4", false)
                .put("condition5", true)
                .build();

        //启动流程实例
        ProcessInstance procInst = runtimeService.startProcessInstanceById(processDefinition.getId(), variables);
        log.info("流程实例ID：{}", procInst.getId());
        TaskQuery taskQuery = taskService.createTaskQuery()
                .processInstanceId(procInst.getId());
        ExecutionQuery executionQuery = runtimeService.createExecutionQuery()
                .processInstanceId(procInst.getId());

        log.info("===========================================================================================");
        //查询并办理第一个用户任务
        Task task1 = taskQuery.singleResult();
        taskService.complete(task1.getId());
        log.info("第一次跳转前，当前任务为：{}", JSON.toJSONString(taskQuery.list(), taskFilter));
        log.info("当前执行实例有：{}", JSON.toJSONString(executionQuery.list(), executionFilter));

        //从UserTask2跳转到UserTask6、UserTask7
        runtimeService.createChangeActivityStateBuilder()
                .processInstanceId(procInst.getId())
                .moveSingleActivityIdToActivityIds("task2",
                        Arrays.asList("task6", "task7"))
                .changeState();
        log.info("第一次跳转后，当前任务为：{}", JSON.toJSONString(taskQuery.list(), taskFilter));
        log.info("当前执行实例有：{}", JSON.toJSONString(executionQuery.list(), executionFilter));

        log.info("===========================================================================================");
        //从UserTask3跳转到UserTask10
        Task task3 = taskQuery.list().stream()
                .filter(t -> "task3".equals(t.getTaskDefinitionKey()))
                .findFirst().get();
        runtimeService.createChangeActivityStateBuilder()
                .moveExecutionToActivityId(task3.getExecutionId(), "task10")
                .changeState();
        log.info("第二次跳转后，当前任务为：{}", JSON.toJSONString(taskQuery.list(), taskFilter));
        log.info("当前执行实例有：{}", JSON.toJSONString(executionQuery.list(), executionFilter));

        //从UserTask4、UserTask10跳转到UserTask12
        runtimeService.createChangeActivityStateBuilder()
                .processInstanceId(procInst.getId())
                .moveActivityIdsToSingleActivityId(Arrays.asList("task4", "task10"),
                        "task12")
                .changeState();
        log.info("第三次跳转后，当前任务为：{}", JSON.toJSONString(taskQuery.list(), taskFilter));
        log.info("当前执行实例有：{}", JSON.toJSONString(executionQuery.list(), executionFilter));

        log.info("===========================================================================================");
        //从UserTask12跳转到UserTask3、UserTask4
        Task task12 = taskQuery.list().stream()
                .filter(t -> "task12".equals(t.getTaskDefinitionKey()))
                .findFirst().get();
        runtimeService.createChangeActivityStateBuilder()
                .moveSingleExecutionToActivityIds(task12.getExecutionId(),
                        Arrays.asList("task3", "task4"))
                .changeState();
        log.info("第四次跳转后，当前任务为：{}", JSON.toJSONString(taskQuery.list(), taskFilter));
        log.info("当前执行实例有：{}", JSON.toJSONString(executionQuery.list(), executionFilter));

        log.info("===========================================================================================");
        //从UserTask3、UserTask4跳转到网关InclusiveGateway2
        List<Task> taskList1 = taskQuery.list().stream()
                .filter(t -> t.getTaskDefinitionKey().equals("task3")
                        || t.getTaskDefinitionKey().equals("task4"))
                .collect(Collectors.toList());
        List<String> executionList1 = taskList1.stream().map(Task::getExecutionId)
                .collect(Collectors.toList());
        runtimeService.createChangeActivityStateBuilder()
                .moveExecutionsToSingleActivityId(executionList1, "inclusiveGateway2")
                .changeState();
        log.info("第五次跳转后，当前任务为：{}", JSON.toJSONString(taskQuery.list(), taskFilter));
        log.info("当前执行实例有：{}", JSON.toJSONString(executionQuery.list(), executionFilter));

        log.info("===========================================================================================");
        //查询并办理UserTask6、UserTask7的任务
        List<Task> taskList2 = taskQuery.list().stream()
                .filter(t -> t.getTaskDefinitionKey().equals("task6")
                        || t.getTaskDefinitionKey().equals("task7"))
                .collect(Collectors.toList());
        taskList2.forEach(task -> {
            taskService.complete(task.getId());
        });
        //查询并办理UserTask11、UserTask12的任务
        List<Task> taskList3 = taskQuery.list().stream()
                .filter(t -> t.getTaskDefinitionKey().equals("task11")
                        || t.getTaskDefinitionKey().equals("task12"))
                .collect(Collectors.toList());
        taskList3.forEach(task -> {
            taskService.complete(task.getId());
        });

        //从UserTask13跳转到UserTask1
        runtimeService.createChangeActivityStateBuilder()
                .processInstanceId(procInst.getId())
                .moveActivityIdTo("task13", "task1")
                .changeState();
        log.info("第六次跳转后，当前任务为：{}", JSON.toJSONString(taskQuery.list(), taskFilter));
        log.info("当前执行实例有：{}", JSON.toJSONString(executionQuery.list(), executionFilter));

        /**
         *  演示结果：
         *  2025-06-18 14:47:14.864  INFO 74452 --- [           main] c.b.n.f.b.l.d.j.g.DynamicJumpGatewayTest : 流程定义ID：gatewayDynamicJumpProcess:1:207504
         * 2025-06-18 14:47:14.946  INFO 74452 --- [           main] c.b.n.f.b.l.d.j.g.DynamicJumpGatewayTest : 流程实例ID：207505
         * 2025-06-18 14:47:14.947  INFO 74452 --- [           main] c.b.n.f.b.l.d.j.g.DynamicJumpGatewayTest : ===========================================================================================
         * 2025-06-18 14:47:15.265  INFO 74452 --- [           main] c.b.n.f.b.l.d.j.g.DynamicJumpGatewayTest : 第一次跳转前，当前任务为：[{"executionId":"207511","id":"207524","name":"UserTask2","taskDefinitionKey":"task2"},{"executionId":"207518","id":"207526","name":"UserTask3","taskDefinitionKey":"task3"},{"executionId":"207519","id":"207528","name":"UserTask4","taskDefinitionKey":"task4"}]
         * 2025-06-18 14:47:15.294  INFO 74452 --- [           main] c.b.n.f.b.l.d.j.g.DynamicJumpGatewayTest : 当前执行实例有：[{"id":"207505","isScope":true,"processInstanceId":"207505"},{"activityId":"task2","id":"207511","isScope":false,"parentId":"207505","processInstanceId":"207505"},{"activityId":"task3","id":"207518","isScope":false,"parentId":"207505","processInstanceId":"207505"},{"activityId":"task4","id":"207519","isScope":false,"parentId":"207505","processInstanceId":"207505"}]
         * 2025-06-18 14:47:15.345  INFO 74452 --- [           main] c.b.n.f.b.l.d.j.g.DynamicJumpGatewayTest : 第一次跳转后，当前任务为：[{"executionId":"207518","id":"207526","name":"UserTask3","taskDefinitionKey":"task3"},{"executionId":"207519","id":"207528","name":"UserTask4","taskDefinitionKey":"task4"},{"executionId":"207529","id":"207532","name":"UserTask6","taskDefinitionKey":"task6"},{"executionId":"207530","id":"207534","name":"UserTask7","taskDefinitionKey":"task7"}]
         * 2025-06-18 14:47:15.352  INFO 74452 --- [           main] c.b.n.f.b.l.d.j.g.DynamicJumpGatewayTest : 当前执行实例有：[{"id":"207505","isScope":true,"processInstanceId":"207505"},{"activityId":"task3","id":"207518","isScope":false,"parentId":"207505","processInstanceId":"207505"},{"activityId":"task4","id":"207519","isScope":false,"parentId":"207505","processInstanceId":"207505"},{"activityId":"task6","id":"207529","isScope":false,"parentId":"207505","processInstanceId":"207505"},{"activityId":"task7","id":"207530","isScope":false,"parentId":"207505","processInstanceId":"207505"}]
         * 2025-06-18 14:47:15.353  INFO 74452 --- [           main] c.b.n.f.b.l.d.j.g.DynamicJumpGatewayTest : ===========================================================================================
         * 2025-06-18 14:47:15.403  INFO 74452 --- [           main] c.b.n.f.b.l.d.j.g.DynamicJumpGatewayTest : 第二次跳转后，当前任务为：[{"executionId":"207519","id":"207528","name":"UserTask4","taskDefinitionKey":"task4"},{"executionId":"207529","id":"207532","name":"UserTask6","taskDefinitionKey":"task6"},{"executionId":"207530","id":"207534","name":"UserTask7","taskDefinitionKey":"task7"},{"executionId":"207535","id":"207537","name":"UserTask10","taskDefinitionKey":"task10"}]
         * 2025-06-18 14:47:15.407  INFO 74452 --- [           main] c.b.n.f.b.l.d.j.g.DynamicJumpGatewayTest : 当前执行实例有：[{"id":"207505","isScope":true,"processInstanceId":"207505"},{"activityId":"task4","id":"207519","isScope":false,"parentId":"207505","processInstanceId":"207505"},{"activityId":"task6","id":"207529","isScope":false,"parentId":"207505","processInstanceId":"207505"},{"activityId":"task7","id":"207530","isScope":false,"parentId":"207505","processInstanceId":"207505"},{"activityId":"task10","id":"207535","isScope":false,"parentId":"207505","processInstanceId":"207505"}]
         * 2025-06-18 14:47:15.449  INFO 74452 --- [           main] c.b.n.f.b.l.d.j.g.DynamicJumpGatewayTest : 第三次跳转后，当前任务为：[{"executionId":"207529","id":"207532","name":"UserTask6","taskDefinitionKey":"task6"},{"executionId":"207530","id":"207534","name":"UserTask7","taskDefinitionKey":"task7"},{"executionId":"207538","id":"207540","name":"UserTask12","taskDefinitionKey":"task12"}]
         * 2025-06-18 14:47:15.454  INFO 74452 --- [           main] c.b.n.f.b.l.d.j.g.DynamicJumpGatewayTest : 当前执行实例有：[{"id":"207505","isScope":true,"processInstanceId":"207505"},{"activityId":"task6","id":"207529","isScope":false,"parentId":"207505","processInstanceId":"207505"},{"activityId":"task7","id":"207530","isScope":false,"parentId":"207505","processInstanceId":"207505"},{"activityId":"task12","id":"207538","isScope":false,"parentId":"207505","processInstanceId":"207505"}]
         * 2025-06-18 14:47:15.454  INFO 74452 --- [           main] c.b.n.f.b.l.d.j.g.DynamicJumpGatewayTest : ===========================================================================================
         * 2025-06-18 14:47:15.526  INFO 74452 --- [           main] c.b.n.f.b.l.d.j.g.DynamicJumpGatewayTest : 第四次跳转后，当前任务为：[{"executionId":"207529","id":"207532","name":"UserTask6","taskDefinitionKey":"task6"},{"executionId":"207530","id":"207534","name":"UserTask7","taskDefinitionKey":"task7"},{"executionId":"207541","id":"207544","name":"UserTask3","taskDefinitionKey":"task3"},{"executionId":"207542","id":"207546","name":"UserTask4","taskDefinitionKey":"task4"}]
         * 2025-06-18 14:47:15.532  INFO 74452 --- [           main] c.b.n.f.b.l.d.j.g.DynamicJumpGatewayTest : 当前执行实例有：[{"id":"207505","isScope":true,"processInstanceId":"207505"},{"activityId":"task6","id":"207529","isScope":false,"parentId":"207505","processInstanceId":"207505"},{"activityId":"task7","id":"207530","isScope":false,"parentId":"207505","processInstanceId":"207505"},{"activityId":"task3","id":"207541","isScope":false,"parentId":"207505","processInstanceId":"207505"},{"activityId":"task4","id":"207542","isScope":false,"parentId":"207505","processInstanceId":"207505"}]
         * 2025-06-18 14:47:15.532  INFO 74452 --- [           main] c.b.n.f.b.l.d.j.g.DynamicJumpGatewayTest : ===========================================================================================
         * 2025-06-18 14:47:15.610  INFO 74452 --- [           main] c.b.n.f.b.l.d.j.g.DynamicJumpGatewayTest : 第五次跳转后，当前任务为：[{"executionId":"207529","id":"207532","name":"UserTask6","taskDefinitionKey":"task6"},{"executionId":"207530","id":"207534","name":"UserTask7","taskDefinitionKey":"task7"},{"executionId":"207548","id":"207553","name":"UserTask12","taskDefinitionKey":"task12"}]
         * 2025-06-18 14:47:15.615  INFO 74452 --- [           main] c.b.n.f.b.l.d.j.g.DynamicJumpGatewayTest : 当前执行实例有：[{"id":"207505","isScope":true,"processInstanceId":"207505"},{"activityId":"task6","id":"207529","isScope":false,"parentId":"207505","processInstanceId":"207505"},{"activityId":"task7","id":"207530","isScope":false,"parentId":"207505","processInstanceId":"207505"},{"activityId":"task12","id":"207548","isScope":false,"parentId":"207505","processInstanceId":"207505"}]
         * 2025-06-18 14:47:15.616  INFO 74452 --- [           main] c.b.n.f.b.l.d.j.g.DynamicJumpGatewayTest : ===========================================================================================
         * 2025-06-18 14:47:15.798  INFO 74452 --- [           main] c.b.n.f.b.l.d.j.g.DynamicJumpGatewayTest : 第六次跳转后，当前任务为：[{"executionId":"207568","id":"207570","name":"UserTask1","taskDefinitionKey":"task1"}]
         * 2025-06-18 14:47:15.803  INFO 74452 --- [           main] c.b.n.f.b.l.d.j.g.DynamicJumpGatewayTest : 当前执行实例有：[{"id":"207505","isScope":true,"processInstanceId":"207505"},{"activityId":"task1","id":"207568","isScope":false,"parentId":"207505","processInstanceId":"207505"}]
         **/
    }
}
